package com.norriekoelle.virtualsensors.kinect.hotspots;

import java.util.Date;

import android.app.AlertDialog;
import android.app.Dialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Typeface;
import android.hardware.Sensor;
import android.hardware.SensorEvent;
import android.hardware.SensorEventListener;
import android.hardware.SensorManager;
import android.net.Uri;
import android.os.Bundle;
import android.os.Environment;
import android.os.Vibrator;
import android.text.format.DateFormat;
import android.util.Log;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.Window;
import android.widget.Button;
import android.widget.EditText;
import android.widget.TextView;

import com.norriekoelle.virtualsensors.kinect.R;
import com.norriekoelle.virtualsensors.kinect.ConnectionManager;
import com.norriekoelle.virtualsensors.kinect.LogToFile;

/**
 * Application for running the client, logging accelerometer data 
 * and displaying content on screen
 * @author norrielm
 *
 */
public class HotspotActivity extends ClientActivity implements SensorEventListener {
	//Log
	private LogToFile log;	
	public static boolean doLog = false;
	//Client
	private ConnectionManager conn;
	//Sensors
	private SensorManager sensorMgr = null;
	private long lastTime = -1;
	private float[] gravity = new float[3];
	private float[] linear_acceleration=new float[3];
	private String chosenApp = null;
	protected static Typeface font;
	
	
	/** Called when the activity is first created. */
    @Override
    public void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        requestWindowFeature(Window.FEATURE_NO_TITLE);
        setContentView(R.layout.hotspots);
        message("starting...");   
    
        conn = new ConnectionManager(this);
        
        //Set up hotspot button listener
        Button b = (Button)this.findViewById(R.id.hotButton);
        b.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
			/*	EditText e = (EditText)findViewById(R.id.tagBox);
				String text = e.getText().toString().trim();
				conn.send("Hotspot " + text);
				//client.lastHotspot = text;
				
				message("hotspot added : " + text);
				Vibrator v = (Vibrator) getSystemService(VIBRATOR_SERVICE);
				v.vibrate(75);
				
				//display tag here for now
				TextView tag = (TextView)findViewById(R.id.hotText);
				font = Typeface.createFromAsset(getAssets(), "upcll.ttf");
				tag.setTypeface(font);
				tag.setText(text + " added");*/
				
				loadCreateDialog();
				
			}
        });
        
        //Set up logfile button listene	r
        b = (Button)this.findViewById(R.id.logButton);
        b.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				conn.send("log");
				
				if(log==null){
					log = new LogToFile("Exp-" + DateFormat.format("hhmmss", new Date()));
				}else{					
					synchronized(log){ 
						log.close();
						log = new LogToFile("Exp-" + DateFormat.format("hhmmss", new Date()));
					}
				}
				message("new logfile created");
				
				Vibrator v = (Vibrator) getSystemService(VIBRATOR_SERVICE);
				v.vibrate(75);
			}
        });
    } 
    
    public void loadCreateDialog(){
    	final CharSequence[] apps = {"Photos", "Camera", "Books", "Text..."};
    	chosenApp = null;
		AlertDialog.Builder d = new AlertDialog.Builder(this);
		//final DIALOG_ACTION a = action;
		
		d.setSingleChoiceItems(apps, -1, new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,
					int id) {
				chosenApp = apps[id].toString();
				//context.finish();
			}
		});
		
		//final GalleryView gv = new GalleryView(this, d);
		d.setTitle("Create hotspot here")
		//.setView(gv)
		.setCancelable(true)
		.setPositiveButton("OK", 
		new DialogInterface.OnClickListener() {
			public void onClick(DialogInterface dialog,
					int id) {
				if(chosenApp.toLowerCase().equals("text...")){
					loadTextDialog();
				}else{
					createHotspot(chosenApp);
				}
				dialog.cancel();
				//context.finish();
			}
		})
		.setNeutralButton("Cancel", 
				new DialogInterface.OnClickListener() {
					public void onClick(DialogInterface dialog,
							int id) {
						dialog.cancel();
						//context.finish();
					}
				});
		
		d.create();
		d.show();
		
    }
    
    public void loadTextDialog(){
    	final Dialog d = new Dialog(this);
		d.setContentView(R.layout.edit_text);
    	d.setTitle("Add message hotspot");
		//final DIALOG_ACTION a = action;
		
		//final GalleryView gv = new GalleryView(this, d);
		Button b = (Button)d.findViewById(R.id.okbutton);
		b.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				EditText e = (EditText)d.findViewById(R.id.tagBox);
				String text = e.getText().toString().trim();
				
				createHotspot(text);
				d.cancel();
			}
        });
		b = (Button)d.findViewById(R.id.cancelbutton);
		b.setOnClickListener(new OnClickListener(){
			@Override
			public void onClick(View arg0) {
				d.cancel();
				
			}
        });
		
		d.show();
    }
    
    /*public boolean isOnline() {
        ConnectivityManager cm = (ConnectivityManager) getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo netInfo = cm.getActiveNetworkInfo();
        if (netInfo != null && netInfo.isConnected()) {
            return true;
        }
        return false;
    }*/
    
    public void createHotspot(String text){ 
    	if(text==null)
    		return;
   
    	
    	conn.send("Hotspot " + text);
		//client.lastHotspot = text;
		
		message("hotspot added : " + text);
		Vibrator v = (Vibrator) getSystemService(VIBRATOR_SERVICE);
		v.vibrate(75);
		
		//display tag here for now
		TextView tag = (TextView)findViewById(R.id.hotText);
		font = Typeface.createFromAsset(getAssets(), "upcll.ttf");
		tag.setTypeface(font);
		tag.setText(text + " added");	
    }
    
    public void doLog(boolean b){
    	if(b){
    		if(log!=null)
    			log.close();
    		
    		log = new LogToFile("Accel-" + System.currentTimeMillis());
    		// Tell the media scanner about the new file so that it is
            // immediately available to the user.
			sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));
		
    		Log.d("SensorLogger", "New logfile created");
    	}
    	
    	doLog = b;
    }
    
    /**
     * Log message and display status on screen
     * @param message
     */
    public void message(String message){
    	Log.d("AndroidClient",message);
    	
    	TextView statusView = (TextView)this.findViewById(R.id.status);
    	statusView.setText(message);     	
    }
    
    /* ************ BT **************

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.option_menu, menu);
        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        switch (item.getItemId()) {
        case R.id.scan:
            // Launch the DeviceListActivity to see devices and do scan
            Intent serverIntent = new Intent(this, DeviceListActivity.class);
            startActivityForResult(serverIntent, btClient.REQUEST_CONNECT_DEVICE);
            return true;
        case R.id.discoverable:
            // Ensure this device is discoverable by others
            btClient.ensureDiscoverable();
            return true;
        }
        return false;
    }*/

    
    
    /* *************** Sensor **********************/
    
    /**
     * Optional
     */
	@Override
	public void onAccuracyChanged(Sensor sensor, int accuracy) {
	}

	/**
	 * Log sensor values.
	 */
	/*@Override
	public void onSensorChanged(SensorEvent event) {
		int sensor = event.sensor.getType();
		float[] values = event.values;
		
		//Accelerometer
		if (sensor == SensorManager.SENSOR_ACCELEROMETER && client.connected) {
			long currTime = System.currentTimeMillis(); 
			
			//log at fixed rate
			if (lastTime  == -1 || (lastTime) > UPDATE_RATE) {
				lastTime = currTime;
				float x = values[SensorManager.DATA_X];				
				float y = values[SensorManager.DATA_Y];
				float z = values[SensorManager.DATA_Z];
				
				//log when tracking user
				if(doLog)
					log.write(String.format(currTime+" %f %f %f", x,y,z));				
			}
		}
	}*/
	
	public void onSensorChanged(SensorEvent event){		
		
		if (doLog && event.sensor.getType() == Sensor.TYPE_ACCELEROMETER) {
			 long currTime = System.currentTimeMillis();
	         // alpha is calculated as t / (t + dT)
	         // with t, the low-pass filter's time-constant
	         // and dT, the event delivery rate
			 // - no lowpass filter defined here (update rate), this is fine.
			 
			 //check sample rate
			/* Log.d("SensorLogger","Accel: " + (currTime-lastTime) + ">=" + 
					 ((20/1000)*1000));*/
			 if ((currTime-lastTime)>=49){//20Hz
				 lastTime = currTime;
				 final float alpha = 0.8f;
		
		         //remove gravity to get linear acceleration
		         gravity[0] = alpha * gravity[0] + (1 - alpha) * event.values[0];
		         gravity[1] = alpha * gravity[1] + (1 - alpha) * event.values[1];
		         gravity[2] = alpha * gravity[2] + (1 - alpha) * event.values[2];
		
		         linear_acceleration[0] = event.values[0] - gravity[0];
		         linear_acceleration[1] = event.values[1] - gravity[1];
		         linear_acceleration[2] = event.values[2] - gravity[2];
		         
		         if(log!=null){
			 	 log.write(String.format(System.currentTimeMillis()
										+" %f %f %f", 
										linear_acceleration[0],
										linear_acceleration[1],
										linear_acceleration[2]));
		         }
		   /*      Log.d("SensorLogger", String.format("%f %f %f", 
												linear_acceleration[0],
												linear_acceleration[1],
												linear_acceleration[2]));
	         */
			 }
		}
	}
    
	/**
	 * Register the listener onResume
	 */
	@Override
	public void onResume(){
		super.onResume();
		
		if(sensorMgr==null){
			Log.d("SensorLogger", "Registering...");
			//Register accelerometer 
			sensorMgr = (SensorManager) getSystemService(Context.SENSOR_SERVICE);
			Sensor accel = sensorMgr.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);//SensorManager..SENSOR_ACCELEROMETER).get(0);
			
			boolean accelSupported = sensorMgr.registerListener(this, accel,
												SensorManager.SENSOR_DELAY_FASTEST);
			if (!accelSupported) {
				Log.d("SensorLogger", "TYPE_ACCELEROMETER not supported...");
				sensorMgr.unregisterListener(this, accel);
			}else{
				Log.d("SensorLogger", "TYPE_ACCELEROMETER is supported...");
			}
		}
	}
    
	/**
	 * Unregister the listener onPause
	 */
	@Override 
	public void onPause(){
		/*Log.d("SensorLogger", "Unregistering...");
		
		//Unregister accelerometer
		if(sensorMgr != null){
			Sensor accel = sensorMgr.getSensorList(Sensor.TYPE_ACCELEROMETER).get(0);
			sensorMgr.unregisterListener(this, accel);
		}
		sensorMgr = null;*/	
		
		super.onPause();
	}    
	
	/**
	 * Stop receive loop, close logs, tell server we're closing the connection 
	 */
	@Override 
	public void finish(){
		message("closing...");
	//	client.exiting = true;
		
		if(log!=null){
			log.close();
			sendBroadcast(new Intent(Intent.ACTION_MEDIA_MOUNTED, Uri.parse("file://" + Environment.getExternalStorageDirectory())));	
		}
		
		conn.close();
		super.finish();
	}

	@Override
	public void handleMessage(String command) {
		// TODO Auto-generated method stub
		
	}
    
}